home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / wasm201.arc / SPLIT.ASM < prev    next >
Assembly Source File  |  1986-12-28  |  12KB  |  400 lines

  1.  
  2.  Title 'Wolfware Assembler Sample', 'Page Splitter'
  3.  
  4. ;===============================================;
  5. ;           Page Splitter Version 1.00          ;
  6. ;                                               ;
  7. ; This program splits a text file into two new  ;
  8. ; files, one containing all the even pages, and ;
  9. ; the other containing all the odd pages. Pages ;
  10. ; are determined by formfeeds (ASCII 12).       ;
  11. ; Splitting up a file like this allows one to   ;
  12. ; print all the right hand pages, then feed the ;
  13. ; same pages back into the printer (upside      ;
  14. ; down) to print all the left hand pages,       ;
  15. ; resulting in double sided printing. This      ;
  16. ; saves much paper and makes things like        ;
  17. ; a printed documentation look better.          ;
  18. ;                                               ;
  19. ; Once assembled, just type SPLIT and answer    ;
  20. ; the questions.                                ;
  21. ;                                               ;
  22. ; The some of the macros defined in DOS.MAC and ;
  23. ; MISC.MAC are required, thus those two files   ;
  24. ; are are expected on the default drive.        ;
  25. ;===============================================;
  26.  
  27.  Jmp Begin
  28.  
  29.  Include 'Dos.Mac'      ;insert DOS routines
  30.  Include 'Misc.Mac'     ;insert miscellaneous routines
  31.  
  32. ;----- equates
  33.  
  34. Name_Size Equ 30        ;maximum size of file names
  35. Read_Size Equ 20000     ;size of read buffer
  36. Write_Size Equ 10000    ;size of write buffer
  37. Formfeed Equ 12         ;start of new page character
  38. Stack_Size Equ 100h     ;size of stack
  39.  
  40. ;----- status
  41.  
  42. Even  Equ 00000001b     ;even page bit
  43. First Equ 00000010b     ;first even page bit
  44.  
  45. Status Db First         ;status
  46.  
  47. ;----- file information
  48.  
  49. Src_Handle Dw ?         ;source handle
  50. Src_Point  Dw 0         ;data pointer
  51. Src_End    Dw 0         ;end of data pointer
  52. Src_Seg    Dw ?         ;data segment
  53.  
  54. Odd_Handle Dw ?         ;odd pages handle
  55. Odd_Point  Dw 0         ;data pointer
  56. Odd_Seg    Dw ?         ;data segment
  57.  
  58. Eve_Handle Dw ?         ;even pages handle
  59. Eve_Point  Dw 0         ;data pointer
  60. Eve_Seg    Dw ?         ;data segment
  61.  
  62. ;----- opening message
  63.  
  64. Open_Mess Db Offset Mess2 - Offset Mess1
  65.  
  66. Mess1
  67.  Db 13,10
  68.  Db 'File Splitter Version 1.00',13,10
  69.  Db 13,10
  70.  Db 'Extracts the odd and even pages out',13,10
  71.  Db 'of a standard text file and puts them',13,10
  72.  Db 'into their own separate files.',13,10
  73.  Db 13,10
  74. Mess2
  75.  
  76. ;===============================================;
  77. ;                  Main Program                 ;
  78. ;===============================================;
  79.  
  80. Begin
  81.  Trap_Break User_Break  ;trap user break
  82.  Display_String Offset Open_Mess ;opening display
  83.  
  84. ;----- reduce present code segment
  85.  
  86.  Mov Bx, $Size + 100h / 16 +1  ;new size
  87.  Dos_Function 4ah       ;change allocation
  88.  
  89. ;----- switch to new stack
  90.  
  91.  Allocate Stack_Size    ;allocate stack segment
  92.  Jc BadMem              ;jump if error
  93.  
  94.  Cli                    ;int's off
  95.  Mov Ss, Ax             ;segment
  96.  Mov Sp, Stack_Size     ;pointer
  97.  Sti                    ;int's back on
  98.  
  99. ;----- allocate data segments
  100.  
  101.  Allocate Read_Size, Src_Seg    ;allocate source segment
  102.  Jc BadMem                      ;jump if error
  103.  Allocate Write_Size, Odd_Seg   ;allocate odd write segment
  104.  Jc BadMem                      ;jump if error
  105.  Allocate Write_Size, Eve_Seg   ;allocate evem write segment
  106.  Jc BadMem                      ;jump if error
  107.  Jmps Filestar
  108.  
  109. ;----- memory error
  110.  
  111. BadMem
  112.  Bell                           ;sound speaker
  113.  Display_Line 'Insufficient memory' ;message
  114.  Exit 2                         ;exit with error code 2
  115.  
  116. ;----- get files and open
  117.  
  118. Filestar
  119.  Display_String 'File to split: ' ;prompt
  120.  Call Input_Name                ;input file name
  121.  Open Dx, Src_Handle            ;open file, save file handle
  122.  Jc BadFile                     ;jump if could not open
  123.  
  124.  Display_String 'File to receive odd pages: ' ;prompt
  125.  Call Input_Name                ;input file name
  126.  Call Create_File               ;create file
  127.  Mov Odd_Handle, Ax             ;save handle
  128.  Jc BadFile                     ;jump if could not open
  129.  
  130.  Display_String 'File to receive even pages: ' ;prompt
  131.  Call Input_Name                ;input file name
  132.  Call Create_File               ;create file
  133.  Mov Eve_Handle, Ax             ;save handle
  134.  Jc BadFile                     ;jump if could not open
  135.  Jmps Srcloop                   ;jump if ok
  136.  
  137. ;----- file error
  138.  
  139. BadFile
  140.  Bell                           ;sound speaker
  141.  Display_Line 'Error in file'   ;message
  142.  Exit 1                         ;exit with error code 1
  143.  
  144. ;----- process file
  145.  
  146. ;----- read next byte
  147.  
  148. Srcloop
  149.  Mov Bx, Src_Handle     ;handle
  150.  Mov Cx, Read_Size      ;buffer size
  151.  Mov Dx, Src_Seg        ;segment
  152.  Mov Si, Src_Point      ;pointer
  153.  Mov Di, Src_End        ;end pointer
  154.  Call Get_Byte          ;get next byte
  155.  Jc Done                ;jump if done
  156.  
  157.  Mov Src_Point, Si      ;save pointer
  158.  Mov Src_End, Di        ;save end pointer
  159.  
  160. ;----- look for formfeed, the formfeed on 
  161. ;----- the first even page is dropped
  162.  
  163.  Cmp Al, Formfeed       ;check if new page
  164.  Jne Noreverse          ;jump if not
  165.  
  166.  Xor Status, Even       ;flip page type
  167.  Test Status, First     ;check if first even page
  168.  Jz Noreverse           ;jump if not
  169.  Test Status, Even      ;check if really even page
  170.  Jz Noreverse           ;jump if not
  171.  
  172.  And Status, Not First  ;clear first even page bit
  173.  Jmp Srcloop            ;loop back for next byte, skip FF
  174.  
  175. ;----- save byte to odd or even file
  176.  
  177. Noreverse
  178.  Call Divide_Byte       ;write byte to respective file
  179.  Jc Diskfull            ;jump if write error
  180.  Jmp Srcloop            ;loop back for next byte
  181.  
  182. ;----- disk full error
  183.  
  184. Diskfull
  185.  Bell                           ;sound speaker
  186.  Display_Line 'Disk full'       ;message
  187.  Exit 1                         ;exit with error code 1
  188.  
  189. ;----- finished
  190.  
  191. Done
  192.  Close Src_Handle       ;close source file
  193.  
  194.  Mov Bx, Odd_Handle     ;handle
  195.  Mov Cx, Odd_Point      ;bytes in buffer
  196.  Mov Dx, Odd_Seg        ;segment
  197.  Call Write_Bytes       ;write final bytes
  198.  Close Bx               ;close
  199.  
  200.  Mov Bx, Eve_Handle     ;handle
  201.  Mov Cx, Eve_Point      ;bytes in buffer
  202.  Mov Dx, Eve_Seg        ;segment
  203.  Call Write_Bytes       ;write final bytes
  204.  Close Bx               ;close
  205.  
  206.  Display_Line 'Finished' ;final message
  207.  Exit                   ;exit
  208.  
  209. ;===============================================;
  210. ;                    Allocate                   ;
  211. ; Macro to allocate the specified number of     ;
  212. ; bytes and save the segment.                   ;
  213. ;===============================================;
  214.  
  215. Allocate Macro Bytes, Segment
  216.  Mov Bx, Bytes / 16 +1  ;number of paragraphs to allocate
  217.  Dos_Function 48h       ;execute
  218.  If_Exist Segment
  219.    Mov Segment, Ax      ;save segment
  220.  Endif
  221.  Endm
  222.  
  223. ;===============================================;
  224. ;                  Input_Name                   ;
  225. ; Input a file name. DX returns the offset of   ;
  226. ; the name.                                     ;
  227. ;===============================================;
  228.  
  229. Input_Name Proc Near
  230.  Input_String Dx, Name_Size     ;input name
  231.  Inc Dx                         ;skip length byte
  232.  Ret
  233.  Endp
  234.  
  235. ;===============================================;
  236. ;                  Create_File                  ;
  237. ; Create (or truncate) the file whose name is   ;
  238. ; at DX.  AX returns the file handle, or the    ;
  239. ; carry is set if there is an error.            ;
  240. ;===============================================;
  241.  
  242. Create_File Proc Near
  243.  Create Dx, Ax                  ;create
  244.  Ret
  245.  Endp                   ;Create_File
  246.  
  247. ;===============================================;
  248. ;                    Get_Byte                   ;
  249. ; Read another byte from a file.  The input is  ;
  250. ; buffered. The following registers must be     ;
  251. ; set: DX data segment, SI pointer, DI end of   ;
  252. ; bytes, BX file handle, and CX size of buffer. ;
  253. ; Carry set if end of file and no byte          ;
  254. ; returned.  SI an DI are updated and AL        ;
  255. ; returns the byte.                             ;
  256. ;===============================================;
  257.  
  258. Get_Byte Proc Near
  259.  Cmp Si, Di             ;check if buffer empty
  260.  Je Gbread              ;jump if so
  261.  
  262. ;----- get next byte
  263.  
  264.  Push Ds
  265.  Mov Ds, Dx
  266.  Lodsb                  ;load next byte
  267.  Pop Ds
  268.  Clc                    ;clear carry, byte returned
  269.  Ret
  270.  
  271. ;----- read a buffer full
  272.  
  273. Gbread
  274.  Push Bx
  275.  Push Cx
  276.  Push Dx
  277.  Push Ds
  278.  Mov Ds, Dx
  279.  Sub Si, Si             ;pointer to start
  280.  Read Bx, Cx, Si, Di    ;read from file
  281.  Pop Ds
  282.  Pop Dx
  283.  Pop Cx
  284.  Pop Bx
  285.  
  286.  Or Di, Di              ;check if bytes read
  287.  Jnz Get_Byte           ;jump if so, try loading again
  288.  
  289. ;----- done with file
  290.  
  291. Gbempt
  292.  Stc                    ;set carry, finished
  293.  Ret
  294.  Endp                   ;Get_Byte
  295.  
  296. ;===============================================;
  297. ;                  Divide_Byte                  ;
  298. ; Write byte in AL to either odd or even page   ;
  299. ; file.                                         ;
  300. ;===============================================;
  301.  
  302. Divide_Byte Proc Near
  303.  Mov Cx, Write_Size     ;buffer size
  304.  Test Status, Even      ;check if even page
  305.  Jnz Diveve             ;jump if so
  306.  
  307. ;----- store odd page byte
  308.  
  309.  Mov Bx, Odd_Handle     ;handle
  310.  Mov Dx, Odd_Seg        ;segment
  311.  Mov Di, Odd_Point      ;pointer
  312.  Call Put_Byte          ;write
  313.  Mov Odd_Point, Di      ;save pointer
  314.  Ret
  315.  
  316. ;----- store even page byte
  317.  
  318. Diveve
  319.  Mov Bx, Eve_Handle     ;handle
  320.  Mov Dx, Eve_Seg        ;segment
  321.  Mov Di, Eve_Point      ;pointer
  322.  Call Put_Byte          ;write
  323.  Mov Eve_Point, Di      ;save pointer
  324.  Ret
  325.  Endp                   ;Divide_Byte
  326.  
  327. ;===============================================;
  328. ;                    Put_Byte                   ;
  329. ; Write another byte to a file.  The output is  ;
  330. ; buffered. The following registers must be     ;
  331. ; set: DX data segment, DI pointer, BX file     ;
  332. ; handle, and CX size of buffer, AL byte to     ;
  333. ; write.  Carry is set if error  (disk full).   ;
  334. ; DI is updated.                                ;
  335. ;===============================================;
  336.  
  337. Put_Byte Proc Near
  338.  Cmp Di, Cx             ;check if buffer full
  339.  Je Pbwrit              ;jump if so
  340.  
  341. ;----- put next byte
  342.  
  343.  Push Es
  344.  Mov Es, Dx
  345.  Stosb                  ;store byte
  346.  Pop Es
  347.  Clc                    ;clear carry, everything ok
  348.  Ret
  349.  
  350. ;----- write a buffer full
  351.  
  352. Pbwrit
  353.  Push Ax
  354.  Push Bx
  355.  Push Cx
  356.  Push Dx
  357.  Call Write_Bytes       ;write buffer
  358.  Sub Di, Di             ;pointer to start
  359.  Pop Dx
  360.  Pop Cx
  361.  Pop Bx
  362.  Pop Ax
  363.  
  364.  Cmp Si, Cx             ;check if all bytes written
  365.  Je Put_Byte            ;jump if so, now store byte
  366.  
  367. ;----- error writing to file
  368.  
  369.  Stc                    ;set carry, error
  370.  Ret
  371.  Endp                   ;put byte
  372.  
  373. ;===============================================;
  374. ;                  Write_Bytes                  ;
  375. ; Write the number of bytes in CX at DX:0 to    ;
  376. ; the file identified by the handle in BX. SI   ;
  377. ; returns bytes written.                        ;
  378. ;===============================================;
  379.  
  380. Write_Bytes Proc Near
  381.  Push Ds
  382.  Mov Ds, Dx
  383.  Write Bx, Cx, 0, Si    ;write to file
  384.  Pop Ds
  385.  Ret
  386.  Endp                   ;Write_Bytes
  387.  
  388. ;===============================================;
  389. ;                   User_Break                  ;
  390. ; Intercept and process a user break.           ;
  391. ;===============================================;
  392.  
  393. User_Break Proc Far
  394.  Bell                   ;sound speaker
  395.  Display_Line 'User break!!'  ;show message
  396.  Stc                    ;set carry, abort
  397.  Ret                    ;return to system
  398.  Endp
  399.  
  400.